package com.game.utils;

import java.lang.reflect.Field;
import java.util.ArrayList;

import com.game.config.Config;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
/**
 * 关于sqlite教程请看http://justsee.iteye.com/blog/932591
*/
public class GameRMS extends SQLiteOpenHelper {
	public static GameRMS instance;
	
	public GameRMS(Context context) {
		//第三个参数CursorFactory指定在执行查询时获得一个游标实例的工厂类,设置为null,代表使用系统默认的工厂类
		super(context, Config.DB_NAME, null, Config.DATABASE_VERSON);
		Log.i("infos", "初始化GameRMS");
		instance=this;
	}

	/**
	 * 创建数据库表,只创建一次,当执行getwriteAbleDB或getReadAbleDB,找不到对应表则执行*/
	@Override
	public void onCreate(SQLiteDatabase db) {
		Log.i("infos", "开始创建表,表的个数为"+Config.TABLES.length);
		for(int i=0;i<Config.TABLES.length;i++){
			String sql= createTableSql(Config.TABLES[i]);
			Log.i("infos", sql);
			if(sql!=null)
				db.execSQL(sql);
		}
	}

	/**
	 * 升级数据库调用,当数据库版本不一致时调用*/
	@Override
	public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
		Log.i("infos", "升级数据库,测试版本删除旧表,正确做法是保存用户数据");
		for(int i=0;i<Config.TABLES.length;i++){
			Log.i("infos", "正在删除表"+Config.TABLES[i]);
			db.execSQL("DROP TABLE IF EXISTS "+Config.TABLES[i]);
		}
        onCreate(db);
	}
	
	/**
	 * 生成创建表的sql
	 * ex:"create table users (id INTEGER primary key autoincrement,score text,num text,music text)"*/
	public String createTableSql(String tableName){
		try {
			String calssName="com.game.entity."+tableName;
			//根据表名获取class
			Class entityClass = Class.forName(calssName);
			//根据表名获取变量名
			Field[] fields = entityClass.getDeclaredFields();
			StringBuilder sql=new StringBuilder("CREATE TABLE IF NOT EXISTS ");
			sql.append(tableName);//表名
			sql.append(" (id INTEGER PRIMARY KEY AUTOINCREMENT ");//id 自增长
			for(int i=0;i<fields.length;i++){//其他字段
				String varName = fields[i].getName();
				String varType = fields[i].getType().toString();
				String realType =null;
				if(varType.endsWith("String")){
					realType="TEXT";
				}else{
					realType="INTEGER";
				}
				sql.append(","+varName+" "+realType);
			}
			sql.append(")");
			return sql.toString();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
			return null;
		}
	}
	
	//------------------------------------------------------------增
	/**把传入的entity插入到Table中
	* */
	public boolean insertIntoTable(Object entity){
		//获得可写的数据库
		 SQLiteDatabase db = this.getWritableDatabase();
		 ContentValues values = getContentValuesWithEntity(entity);
		 //获取表名,插入数据
		 db.insert(getTableName(entity.getClass()), null, values);
		 db.close();
		 values.clear();
		 return true;
	}
	
	/**把传入的entity插入到Table中
	 * ex:"insert into person(name, age) values('传智播客', 4)"*/
	public boolean insertIntoTableSQL(Object entity){
		//获得可写的数据库
		 SQLiteDatabase db = this.getWritableDatabase();
		 
		 //动态生成sql
		 StringBuilder  sql=new StringBuilder();
		 sql.append("INSERT INTO ");
		 //获取类名作为表名
		 sql.append(getTableName(entity.getClass()));
		 sql.append("(");
		 //获取变量数组
		 Field[] fields = entity.getClass().getDeclaredFields();
		 for(int i = 0 , len = fields.length; i < len; i++) {
				 if(!(i==0))
				 	sql.append(",");
	            // 对于每个属性，获取属性名
	            String varName = fields[i].getName();
	            sql.append(varName);
	        }
		 sql.append(")VALUES(");
		 for(int i = 0 , len = fields.length; i < len; i++) {
			 String varType = fields[i].getType().toString();
			 if(!(i==0))
			 	sql.append(",");
			 try {
	             // 获取原来的访问控制权限
	             boolean accessFlag = fields[i].isAccessible();
	             // 修改访问控制权限
	             fields[i].setAccessible(true);
	             // 获取变量值
	             Object value = fields[i].get(entity);
	             if(varType.endsWith("String"))//处理字符串
	            	 sql.append("'"+value+"'");
	             else
	            	 sql.append(value);
	             // 恢复访问控制权限
	             fields[i].setAccessible(accessFlag);
	         } catch (IllegalArgumentException ex) {
	             ex.printStackTrace();
	         } catch (IllegalAccessException ex) {
	             ex.printStackTrace();
	         }
       }
		 sql.append(")");
		 System.out.println(sql);
		 db.execSQL(sql.toString());
		 db.close();
		 return true;
	}
	
	//------------------------------------------------------------查
	/**
	 * 从表中搜索所有数据
	 * @param tableName 表名*/
	public ArrayList<Object>  selectFromTable(String tableName){
		String sql="SELECT * FROM "+tableName;
		return executeQuery(tableName,sql,null);
	}
	
	
	/**
	 * 从表中搜索所有数据
	 * @param tableName 表名
	 * @param condition 条件语句*/
	public ArrayList<Object>  selectFromTable(String tableName,String condition){
		String sql="SELECT * FROM "+tableName+" "+condition;
		return executeQuery(tableName,sql,null);
	}
	
	/**
	 * 从表中搜索所有数据
	 * @param tableName 表名
	 * @param condition 条件语句
	 * @param values 占位符的值*/
	public ArrayList<Object>  selectFromTable(String tableName,String condition,String[] values){
		String sql="SELECT * FROM "+tableName+" "+condition;
		return executeQuery(tableName,sql,values);
	}
	
	/**
	 * 根据条件,从表中搜索数据
	 * @param tableName 表名
	 * @param sql 查询语句
	 * @param values 占位符的值*/
	public ArrayList<Object> executeQuery(String tableName,String sql,String[] values){
		try {
		String className="com.game.entity."+tableName;
		//根据表名获取class
		Class entityClass = Class.forName(className);
		
		SQLiteDatabase db=this.getReadableDatabase();
		//查询所有记录
//		Cursor cursor=db.query(tableName,null,null,null,null,null,null);
//		Cursor cursor = db.query("person", new String[]{"personid,name,age"}, "name like ?", new String[]{"%溧阳%"}, null, null, "personid desc", "1,2");
//		上面代码用于从person表中查找name字段含有“传智”的记录，匹配的记录按personid降序排序，对排序后的结果略过第一条记录，只获取2条记录。
//		query(table, columns, selection, selectionArgs, groupBy, having, orderBy, limit)方法各参数的含义：
//		table：表名。相当于select语句from关键字后面的部分。如果是多表联合查询，可以用逗号将两个表名分开。
//		columns：要查询出来的列名。相当于select语句select关键字后面的部分。
//		selection：查询条件子句，相当于select语句where关键字后面的部分，在条件子句允许使用占位符“?”
//		selectionArgs：对应于selection语句中占位符的值，值在数组中的位置与占位符在语句中的位置必须一致，否则就会有异常。
//		groupBy：相当于select语句group by关键字后面的部分
//		having：相当于select语句having关键字后面的部分
//		orderBy：相当于select语句order by关键字后面的部分，如：personid desc, age asc;
//		limit：指定偏移量和获取的记录数，相当于select语句limit关键字后面的部分。
		Log.i("infos", "执行sql "+sql);
		Cursor cursor = db.rawQuery(sql, values);
		//用于保存数据集
		ArrayList<Object> resultSet= new ArrayList<Object>();
		while(cursor.moveToNext()){
//			Log.i("infos", "找到数据");
			//创建实体类接收数据
			Object entity=entityClass.newInstance();
			Field[] fields = entity.getClass().getDeclaredFields();
			for(int i=0;i<fields.length;i++){
				String varName = fields[i].getName();
				String varType = fields[i].getType().toString();
				// 获取原来的访问控制权限
	             boolean accessFlag = fields[i].isAccessible();
	             // 修改访问控制权限
	             fields[i].setAccessible(true);
				if(varType.endsWith("String"))
					fields[i].set(entity, cursor.getString(cursor.getColumnIndex(varName)));
				else
					fields[i].set(entity, cursor.getInt(cursor.getColumnIndex(varName)));
				 // 恢复访问控制权限
	             fields[i].setAccessible(accessFlag);
			}
			resultSet.add(entity);
		}
		db.close();
		cursor.close();
		return resultSet;
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}
	
	//------------------------------------------------------------删
	/**
	 * 删除所有
	 * @param tableName 表名*/
	public void deleteFromTable(String tableName){
		deleteFromTable(tableName,null,null);
	}
	
	/**
	 * 删除
	 * @param tableName 表名
	 * @param condition 条件*/
	public void deleteFromTable(String tableName,String condition){
		deleteFromTable(tableName,condition,null);
	}
	
	/**
	 * 删除
	 * @param tableName 表名
	 * @param condition 条件 delete的condition不用加上where
	 * @param values 条件中占位符的值*/
	public void deleteFromTable(String tableName,String condition,String[] values){
		SQLiteDatabase db = this.getWritableDatabase();
		db.delete(tableName, condition, values);
		db.close();
	}
	
	/**
	 * 执行sql*/
	public void executeSql(String sql){
		SQLiteDatabase db = this.getWritableDatabase();
		db.execSQL(sql);
		db.close();
	}
	
	//------------------------------------------------------------改
	/**
	 * 更新
	 * @param tableName 表名
	 * @param condition 条件*/
	public void updateTable(Object entity,String condition){
		updateTable(entity,condition,null);
	}
	
	/**
	 * 更新
	 * @param tableName 表名
	 * @param condition 条件
	 * @param values 条件中占位符的值*/
	public void updateTable(Object entity,String condition,String[] values){
		 SQLiteDatabase db = this.getWritableDatabase();
		 ContentValues contentValues = getContentValuesWithEntity(entity);
		 db.update(getTableName(entity.getClass()), contentValues, condition,values); 
		 //获取表名,插入数据
		 db.close();
		 contentValues.clear();
		 db.close();
	}
	
	/**
	 * 获取类名*/
	public static String getTableName(Class<?> c){
		String fullName=c.toString().split(" ")[1];
		if(fullName.indexOf('.')!=-1){
			fullName=fullName.substring(fullName.lastIndexOf('.')+1);
		}
		return fullName;
	}
	
	/**
	 * 把entity的值保存到ContentValues中并返回*/
	public ContentValues getContentValuesWithEntity(Object entity){
		ContentValues contentValues = new ContentValues();
		//获取变量数组
		 Field[] fields = entity.getClass().getDeclaredFields();
		 for(int i = 0 , len = fields.length; i < len; i++) {
			 //变量名
			 String varName = fields[i].getName();
			 //变量类型
			 String varType = fields[i].getType().toString();
			 try {
	             // 获取原来的访问控制权限
	             boolean accessFlag = fields[i].isAccessible();
	             // 修改访问控制权限
	             fields[i].setAccessible(true);
	             // 获取变量值
	             Object value = fields[i].get(entity);
	             if(value!=null){
	            	 //是string类型
	            	 if(varType.endsWith("String"))//处理字符串
	            		 contentValues.put(varName,(String)value);
		             else{
		            	 //是int类型
		            	 if(Integer.parseInt(value.toString())!=0)
		            		 contentValues.put(varName,Integer.parseInt(value.toString()));
		             }
		            	
	             }
	             // 恢复访问控制权限
	             fields[i].setAccessible(accessFlag);
	         } catch (IllegalArgumentException ex) {
	             ex.printStackTrace();
	         } catch (IllegalAccessException ex) {
	             ex.printStackTrace();
	         }
      }
		 return contentValues;
	}
}